package rabbitmq

import (
	"app/util"
	"errors"
)

type Container struct {
	ChannelPool map[string]*Channel
	PushPool    map[string]*Channel
	PopPool     map[string]*Channel
	mqconf      *Conf
}

func NewMgr() *Container {
	m := &Container{}
	m.ChannelPool = make(map[string]*Channel) //连接名称:连接对象
	m.PushPool = make(map[string]*Channel)    //连接名称:发送对象
	m.PopPool = make(map[string]*Channel)     //连接名称:接受对象
	return m
}
func (m *Container) LoadConf(path string) error {

	conf, err := loadconf(path)
	if err != nil {
		return errors.New("Rabbitmq load conf faild")
	}

	return m.parseconf(conf)
}
func (m *Container) parseconf(conf *Conf) error {

	for _, v := range conf.Channels {
		conn := NewChannel(&v)
		if conn == nil {
			util.Error("Rabbitmq New Channel is nil")
		} else {
			m.ChannelPool[conn.channelconf.Name] = conn
		}

	}

	if len(m.ChannelPool) == 0 {
		util.Error("Rabbitmq connectpool is zero")
		return errors.New("connectpool is zero")
	} else {
		util.Info("Rabbitmq connectpool is %d", len(m.ChannelPool))
	}

	for _, v := range conf.Exchanges {

		if value, ok := m.ChannelPool[v.Channel]; !ok {
			util.Warning("Rabbitmq nofind channel as Exchanges%s", v.Channel)
			continue
		} else {
			value.DeclareExchange(&v)
		}
	}

	for _, v := range conf.Queue {
		if value, ok := m.ChannelPool[v.Channel]; !ok {
			util.Warning("Rabbitmq nofind channel as Queue %s", v.Channel)
			continue
		} else {
			value.DeclareQueue(&v)
		}
	}

	for _, v := range conf.Pusher {
		if value, ok := m.ChannelPool[v.Channel]; !ok {
			util.Warning("Rabbitmq nofind channel as Pusher %s", v.Channel)
			continue
		} else {
			if value.GetExchangeConf().Name == v.Exchange {
				value.DeclarePush(&v)
				m.PushPool[v.Name] = value
			}
		}
	}

	for _, v := range conf.Poper {
		if value, ok := m.ChannelPool[v.Channel]; !ok {
			util.Warning("Rabbitmq nofind channel as Poper %s", v.Channel)
			continue
		} else {
			if value.GetQueueConff().Name == v.QName {
				value.DeclarePop(&v)
				m.PopPool[v.Name] = value
			}
		}
	}

	return nil
}

func (m *Container) GetPush(name string) (*Channel, error) {

	if value, ok := m.PushPool[name]; !ok {
		return nil, errors.New("GetKey no found ")
	} else {
		return value, nil
	}
	return nil, errors.New("GetKey no found")
}

func (m *Container) GetPop(name string) (*Channel, error) {

	if value, ok := m.PopPool[name]; !ok {
		return nil, errors.New("GetKey no found ")
	} else {
		return value, nil
	}
	return nil, errors.New("GetKey no found")
}

func (m *Container) ClosePools() {

	for _, v := range m.ChannelPool {
		v.CloseChannel()
	}
}
